import '../lib/utils/loadEnv';
import {
  StateGraph,
  END,
  Annotation,
  START,
  Command,
} from '@langchain/langgraph';
import { HumanMessage, BaseMessage } from '@langchain/core/messages';
import { getOpenaiInstance } from '../lib/llm/openai';
import { interrupt } from '@langchain/langgraph';
import { MemorySaver } from '@langchain/langgraph';
import * as readline from 'readline';

console.log('%c Line:6 🥕', 'color:#f5ce50', process.env.OPENAI_API_KEY);
const StateAnnotation = Annotation.Root({
  messages: Annotation<BaseMessage[]>({
    reducer: (state, update) => {
      return state.concat(update);
    },
  }),

  userInput: Annotation<string>(),
  next: Annotation<string>(),
});

const checkpointer = new MemorySaver();

const app = () => {
  const llm = getOpenaiInstance();
  // 创建状态图
  const graph = new StateGraph(StateAnnotation)
    .addNode('processUserInput', async (state) => {
      // 创建一个新的人类消息
      const humanMessage = new HumanMessage(state.userInput);
      // 将人类消息添加到历史中
      console.log(
        '%c Line:24 🍑 humanMessage，收到消息，正在处理',
        'color:#b03734',
        humanMessage
      );
      // 返回更新后的消息历史
      return { messages: [humanMessage] };
    })
    .addNode('generateAIResponse', async (state) => {
      // 使用 LLM 生成响应
      const response = await llm.invoke(state.messages);

      // 将 AI 响应添加到历史中
      const newMessages = [...state.messages, response];

      // 返回更新后的消息历史
      return { messages: newMessages };
    })
    .addNode('humanNode', async (state: typeof StateAnnotation.State) => {
      console.log('%c Line:45 🍎 humanNode 暂停开始', 'color:#42b983');
      const value = interrupt(
        `这个结果满足要求吗？请回复【满意】或者【不满意】：\n${
          state.messages[state.messages.length - 1].content
        }`
      );
      console.log('%c Line:46 🥐 value 暂停回复', 'color:#ea7e5c', value);
      if (value.includes('不')) {
        return {
          userInput: '请重新生成一个更好的回答',
          next: 'processUserInput',
        };
      } else {
        return { next: END };
      }
    })

    .addEdge(START, 'processUserInput')
    .addEdge('processUserInput', 'generateAIResponse')
    .addEdge('generateAIResponse', 'humanNode')
    .addConditionalEdges('humanNode', (state) => state.next);

  return graph.compile({
    checkpointer,
  });
};

// 创建一个可重用的图实例
let compiledGraph: any;

// 使用函数运行对话
async function runConversation(
  userInput: string,
  inputThreadId: string | null = null,
  interrupt: boolean
) {
  try {
    // 如果没有已编译的图，则创建一个
    if (!compiledGraph) {
      compiledGraph = app();
    }

    // 生成一个新的线程ID（如果没有提供）
    const threadId = inputThreadId || `thread_${Date.now()}`;
    console.log('%c Line:85 🍕 threadId', 'color:#6ec1c2', threadId);

    // 调用图并处理中断
    const result = await compiledGraph.invoke(
      interrupt ? new Command({ resume: userInput }) : { userInput },
      {
        recursionLimit: 100,
        configurable: {
          thread_id: threadId,
        },
      }
    );

    // 获取线程ID，用于后续对话
    const resultThreadId = threadId;

    // 获取最后一条消息（AI 的响应）
    const lastMessage = result.messages[result.messages.length - 1];

    if (result.__interrupt__?.length > 0) {
    }

    // 返回 AI 的响应内容和线程ID
    return {
      content: lastMessage.content,
      threadId: resultThreadId,
      interrupt: result.__interrupt__,
    };
  } catch (error) {
    console.error('对话出错:', error);
    throw error;
  }
}

// 命令行交互
async function main() {
  console.log('欢迎使用 LangGraphJS 对话系统！输入 "退出" 结束对话。');

  const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout,
  });

  let threadId: string | null = null;

  // 对话循环
  const askQuestion = async ({ interrupt } = { interrupt: false }) => {
    rl.question(interrupt ? '' : '请输入您的问题: ', async (input) => {
      // 检查是否退出
      if (input.toLowerCase() === '退出') {
        console.log('感谢使用，再见！');
        rl.close();
        return;
      }

      try {
        // 运行对话
        const result = await runConversation(input, threadId, interrupt);
        threadId = result.threadId; // 保存线程ID用于后续对话

        if (result.interrupt) {
          console.log(
            '%c Line:167 🥃 AI 询问人类',
            'color:#f5ce50',
            result.interrupt[0].value
          );
        } else {
          console.log('\nAI 响应:', result.content);
          console.log('\n----------------------------\n');
        }

        // 继续对话
        askQuestion({ interrupt: !!result.interrupt });
      } catch (error) {
        console.error('处理对话时出错:', error);
        rl.close();
      }
    });
  };

  // 开始对话
  askQuestion();
}

// 启动程序
main().catch(console.error);
